package com.mydemo.charging.order.service;

import com.mydemo.charging.common.constant.AmqpComponentConst;
import com.mydemo.charging.common.constant.MqttDestinationConst;
import com.mydemo.charging.common.pojo.message.ChargingStartCheckMessage;
import com.mydemo.charging.common.pojo.message.DelayCheckMessage;
import com.mydemo.charging.common.pojo.param.OrderAddParam;
import com.mydemo.charging.common.pojo.vo.VehicleVO;
import com.mydemo.charging.common.protocol.JsonResult;
import com.mydemo.charging.common.utils.CronUtil;
import com.mydemo.charging.common.utils.SnowflakeIdGenerator;
import com.mydemo.charging.order.amqp.AmqpProducer;
import com.mydemo.charging.order.feign.DeviceClient;
import com.mydemo.charging.order.feign.UserClient;
import com.mydemo.charging.order.mqtt.MqttProducer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService{
    @Autowired
    private DeviceClient deviceClient;
    @Autowired
    private UserClient userClient;
    @Autowired
    private MqttProducer<ChargingStartCheckMessage> mqttProducer;
    @Autowired
    private AmqpProducer<DelayCheckMessage> amqpProducer;
    private SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(5,12);
    @Override
    public String createOrder(OrderAddParam param) {
        //1.利用枪id 调用device服务检查枪状态 订单要在 可用的状态下才能继续流程
        checkGun(param.getGunId());
        //2.利用车主id 调用user服务 检查车主状态 检查车辆信息是否完整
        checkUserAndVehicle(param.getUserId());
        //3.生成唯一标识,保证高并发环境下唯一 保证有序(为了海量生成的数据 存在有序的标识,可以高效查询)
        //订单编号生成 可以使用雪花算法
        String billId=idGenerator.nextId()+"";
        //4.给设备发送命令 自检设备 开启充电
        //4.1 主题名字 常量前缀 + param.getPileId()
        String destination= MqttDestinationConst.START_GUN_CHECK_PREFIX+param.getPileId();
        //4.2 组织消息对象 orderNo userId gunId
        ChargingStartCheckMessage startCheckMessage=new ChargingStartCheckMessage();
        startCheckMessage.setOrderNo(billId);
        startCheckMessage.setUserId(param.getUserId());
        startCheckMessage.setGunId(param.getGunId());
        mqttProducer.send(destination,startCheckMessage);
//        //5.发送延迟消息 延迟检查自检结果
//        DelayCheckMessage delayMessage=new DelayCheckMessage();
//        delayMessage.setOrderNo(billId);
//        delayMessage.setUserId(param.getUserId());
//        amqpProducer.sendDelay(delayMessage, AmqpComponentConst.DELAY_BILL_EX);
//        //6.生成计划任务,根据充电预估时长,兜底检查是否充电异常.
//        //估算一个最大充电时间 2分钟
//        String cronExpression = CronUtil.delayCron(1000 * 60 * 2);
//        XxlJobTaskUtil.createJobTask(new RestTemplate(),cronExpression,5,billId);
        return billId;
    }


    private void checkUserAndVehicle(Integer userId) {
        //要求用户得有一个绑定车辆
        log.debug("检查车主车辆信息入参:{}",userId);
        JsonResult<VehicleVO> vehicleVOJsonResult = userClient.bindedVehicle(userId);
        log.debug("检查车主车辆信息结果:{}",vehicleVOJsonResult);
        if(vehicleVOJsonResult.getData()==null){
            throw new RuntimeException("车主没有绑定车辆");
        }
    }

    private void checkGun(Integer gunId) {
        log.debug("检查枪状态入参:{}",gunId);
        //调用设备服务 检查反馈结果
        JsonResult<Boolean> booleanJsonResult = deviceClient.checkGun(gunId);
        log.debug("检查枪状态结果:{}",booleanJsonResult);
        if(!booleanJsonResult.getData()){
            throw new RuntimeException("枪状态异常");
        }
    }
}
